package org.javahispano.javacup.tacticas_aceptadas.psubias.ar.com.psubias.laLegion;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.javahispano.javacup.modelo.Comando;
import org.javahispano.javacup.modelo.ComandoGolpearBalon;
import org.javahispano.javacup.modelo.ComandoIrA;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.TacticaDetalle;

public class LaLegion implements Tactica {

    Posicion saque[]=new Posicion[]{
        new Posicion(  0.00,-50.00),
        new Posicion(  2.00,-35.00),
        new Posicion(-20.00,-30.00),
        new Posicion( 20.00,-30.00),
        new Posicion(-24.00, -5.00),
        new Posicion( -5.00,-23.50),
        new Posicion(  5.00,-23.50),
        new Posicion(  0.00,  0.00),
        new Posicion( -9.50, -0.25),
        new Posicion( 23.00, -8.00),
        new Posicion(  9.50, -0.25)
    };

    Posicion saqueRecibe[]=new Posicion[]{
        new Posicion(  0.00,-50.00),
        new Posicion(  2.00,-35.00),
        new Posicion(-20.00,-30.00),
        new Posicion( 20.00,-30.00),
        new Posicion(-24.00, -5.00),
        new Posicion( -5.00,-23.50),
        new Posicion(  5.00,-23.50),
        new Posicion( -0.00,-10.00),
        new Posicion( -9.50, -0.25),
        new Posicion( 23.00, -8.00),
        new Posicion(  9.50, -0.25)
    };

    TacticaDetalle detalle=new LaLegionDetalle();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    	return saque;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    	return saqueRecibe;
    }

    interface TacticaJugador {
    	
    	public int indice();
    	public List<Comando> IA(SituacionPartido sp);
    	
    }

    public List<Comando> ejecutar(SituacionPartido sp) {
    	return IA(sp);
    }
    
    // Vamos La Legi�n
	Random rnd = new Random();
	Posicion balonPosAnterior[] = new Posicion[]{
			new Posicion(0, 1),
			new Posicion(0, 1),
			new Posicion(0, 1),
			new Posicion(0, 1),
			new Posicion(0, 1)
	}; 
	
	Posicion tiroArco = new Posicion(0, Constantes.LARGO_CAMPO_JUEGO / 2);
    ArrayList<Comando> comandos = new ArrayList<Comando>();
    Posicion LineaArqueroInfIzq = new Posicion(-34, -51);
    Posicion LineaArqueroInfDer = new Posicion(34, -51);
    int iteracionesSaque =0;
    LaLegionLib laLegionLib = new LaLegionLib(); 
    
    private List<Comando> IA(SituacionPartido sp){
    	
    	comandos.clear();
    	
    	comandos.addAll(IAArquero(sp));
    	for (int i = 1; i < 11; i++) {
    		comandos.addAll(IAJugador(i, sp));
    	}
    	
    	for (int i = 4; i > 0; i--) { 
    		balonPosAnterior[i] = balonPosAnterior[i].moverPosicion(balonPosAnterior[i-1].getX() - balonPosAnterior[i].getX(), balonPosAnterior[i-1].getY() - balonPosAnterior[i].getY());
    	}
    	balonPosAnterior[0] = balonPosAnterior[0].moverPosicion(sp.balon().getX() - balonPosAnterior[0].getX(), sp.balon().getY() - balonPosAnterior[0].getY());
    	
    	return comandos;
    	
    }
    
    private List<Comando> IAArquero(SituacionPartido sp){
    	final int indice = 0;
    	
    	List<Comando> comandos = new ArrayList<Comando>();    	
    	if (sp.saco() && zonaSaque[0].dentroDelArea(sp.balon())) {
    		comandos.add(new ComandoIrA(indice, sp.balon()));
    	}
    	else {
    		if (sp.balon().getY()>0){
    			comandos.add(new ComandoIrA(indice, zonas(indice, sp).getDescanso()));
    		}
    		else {
    			if ((balonPosAnterior[4].distancia(sp.balon()) < 0.3) && (sp.alturaBalon()< 0.1) && (zonas(indice, sp).dentroDelArea(sp.balon()))) {
    				comandos.add(new ComandoIrA(indice, sp.balon()));
    			}
    			else {
	    	    	Posicion posArquero = Posicion.Interseccion(LineaArqueroInfIzq, LineaArqueroInfDer, sp.balon(), balonPosAnterior[4]);
	    	    	if (posArquero==null){
	    	    		comandos.add(new ComandoIrA(indice,  zonas(indice, sp).getDescanso()));
	    	    	}
	    	    	else {
	    	    		if (posArquero.getX() > 0) {
	    		    		if (Constantes.LARGO_ARCO / 2 < posArquero.getX()) {
	    		    			posArquero = posArquero.setPosicion(Constantes.LARGO_ARCO / 1.99, posArquero.getY());
	    		    		}
	    		    	} else {
	    		    		if (Constantes.LARGO_ARCO / -2 > posArquero.getX()) {
	    		    			posArquero = posArquero.setPosicion(Constantes.LARGO_ARCO / -1.99, posArquero.getY());
	    		    		}
	    		    	}
	    		    	comandos.add(new ComandoIrA(indice, posArquero));
	    	    	}
	    		}
    		}
    	}

    	if (laLegionLib.puedeRematar(indice, sp)) {
    		if (sp.balon().getX()<0) {
    			comandos.add(new ComandoGolpearBalon(indice,sp.misJugadores()[2], 1, true));
    		} else {
    			comandos.add(new ComandoGolpearBalon(indice,sp.misJugadores()[3], 1, true));
    		}
    	}

    	return comandos;        	
    }
    
    private List<Comando> IAJugador(int indice, SituacionPartido sp){

    	List<Comando> comandos = new ArrayList<Comando>();
    	
    	//movimiento
    	if (sp.saco() && zonaSaque[indice].dentroDelArea(sp.balon()) && !zonaSaque[0].dentroDelArea(sp.balon())) {
    		comandos.add(new ComandoIrA(indice, sp.balon()));
    	}
    	else {
	    	if ((!sp.saco()) && (zonas(indice, sp).dentroDelArea(sp.balon()))) 
	    			comandos.add(new ComandoIrA(indice, sp.balon()));
	    	else 
	    			comandos.add(new ComandoIrA(indice, zonas(indice, sp).getDescanso()));
    	}
    	
    	// golpe/regate
    	if (laLegionLib.puedeRematar(indice, sp)) {
    		float r = rnd.nextFloat();
    		Posicion arqueroRival=sp.rivales()[0];

    		for (int i=0; i<=10; i++) {
    			if (sp.detalleJugadoresRivales()[i].esPortero()) {
    				arqueroRival = sp.rivales()[i];
    			}
    		}
    		
    		if ((sp.balon().getY()>0) && (sp.balon().getY()/35<r)){
    			Posicion posTiro;
    			if (Math.abs(arqueroRival.distancia(Constantes.posteDerArcoSup) - arqueroRival.distancia(Constantes.posteIzqArcoSup))> 1.5) {
    				if (sp.balon().getX()>0) {
    					posTiro = Constantes.posteDerArcoSup.moverPosicion(-1, 0);
    				} else {
    					posTiro = Constantes.posteIzqArcoSup.moverPosicion(1, 0);
    				}
    				
    			} else {
    				posTiro = new Posicion(-2 + (4 * rnd.nextFloat()), Constantes.LARGO_CAMPO_JUEGO / 2);
    			}
    			comandos.add(new ComandoGolpearBalon(indice, posTiro, 1, laLegionLib.anguloPase(indice, sp, sp.balon().distancia(posTiro), 1)));
    			}
    		else {
	    		if ((sp.misJugadores()[indice].getY() > 0) && (sp.misJugadores()[indice].getY()/45<r)) { 
	    			r = rnd.nextFloat();
	    			if (r < 0.8) {

	    				Zona areaI = new Zona(new Posicion(sp.balon().getX()-6, sp.balon().getY()), new Posicion(sp.balon().getX(), sp.balon().getY()+4));
		    			Zona areaD = new Zona(new Posicion(sp.balon().getX(), sp.balon().getY()), new Posicion(sp.balon().getX()-6, sp.balon().getY()+4));
		    			Zona areaA = new Zona(new Posicion(sp.balon().getX()-3, sp.balon().getY()), new Posicion(sp.balon().getX()+3, sp.balon().getY()+4));
		    			
		    			if (areaI.rivalesDentroDelArea(sp)<areaD.rivalesDentroDelArea(sp)) {
		    				if (areaI.rivalesDentroDelArea(sp)<areaA.rivalesDentroDelArea(sp)) {
		    					comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup.moverPosicion(-27, -5), 0.6, false));
		    					}
		    				else {
		    					comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup, 0.6, false));}
			    			} 
		    			else 
		    				{if (areaD.rivalesDentroDelArea(sp)<areaA.rivalesDentroDelArea(sp)) {
		    					comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup.moverPosicion(27, -5), 0.6, false));}
		    				else {
		    					comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup, 0.6, false));		    					
		    				}
		    			}
	    			}
	    			else
	    			{	
	    				r = rnd.nextFloat();
		    			if (r < 0.5) {
			    			comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup, 0.6, false));
		    			} else if (r < 0.75) {
		    				comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup.moverPosicion(-27, -5), 0.6, false));
		    			} else {
		    				comandos.add(new ComandoGolpearBalon(indice, Constantes.centroArcoSup.moverPosicion(27, -5), 0.6, false));
		    			}
	    			}
	    		}
	    		else {
	    			r = rnd.nextFloat();
	    			int paseA = laLegionLib.destinoPase(indice, sp, new Zona(zonas(indice, sp).getNoPaseSupIzq(), zonas(indice, sp).getNoPaseInfDer()));
	    			if (paseA == 12) {
	        			Posicion posTiro = new Posicion(-2 + (4 * rnd.nextFloat()), Constantes.LARGO_CAMPO_JUEGO / 2);
	        			comandos.add(new ComandoGolpearBalon(indice, posTiro, 1, laLegionLib.anguloPase(indice, sp, sp.balon().distancia(posTiro), 1)));
	    			} else {
	    				comandos.add(new ComandoGolpearBalon(indice,sp.misJugadores()[paseA].moverPosicion(0, sp.balon().distancia(sp.misJugadores()[paseA])/10), laLegionLib.fuerzaPase(sp, sp.misJugadores()[paseA]), true));
	    			}
	    			
	    		}
    		}
    	}

    	return comandos;         	
    }
    
    private Zona zonas(int indice, SituacionPartido sp) {
    	return zonasNormal[indice];
    }
    
    Zona zonasNormal[] = new Zona[]{
    			     // zona movimiento                              // descanso             //no pase
    		new Zona(new Posicion( -7, -45), new Posicion(  7, -52), new Posicion(  0, -50), new Posicion(-34,-53), new Posicion( 34,-20)), //Lucho
    		new Zona(new Posicion(-34, -25), new Posicion( 34, -52), new Posicion(  0, -33), new Posicion(-25,-53), new Posicion( 25,-20)), //Gusta
    		new Zona(new Posicion(-34,   0), new Posicion(  0, -52), new Posicion(-22, -30), new Posicion(-25,-53), new Posicion( 25,-20)), //Tongha
    		new Zona(new Posicion(  0,   0), new Posicion( 34, -52), new Posicion( 22, -30), new Posicion(-25,-53), new Posicion( 25,-20)), //Dani
    		new Zona(new Posicion(-20,   0), new Posicion( 20, -30), new Posicion(  0, -20), new Posicion(-20,-53), new Posicion( 20,-20)), //Guille
    		new Zona(new Posicion(-20,  10), new Posicion( 20, -20), new Posicion(  0,   0), new Posicion(-20,-53), new Posicion( 20,-10)), //Dari
    		new Zona(new Posicion(-34,  25), new Posicion(  0, -25), new Posicion(-26,   0), new Posicion(-34,-53), new Posicion( 34,  0)), //Juani    		
    		new Zona(new Posicion(-30 , 25), new Posicion( 30, -10), new Posicion(  0,  20), new Posicion(-34,-53), new Posicion( 34, 20)), //Tano
    		new Zona(new Posicion(-34,  52), new Posicion( 15,  20), new Posicion( -8,  32), new Posicion(-34,-53), new Posicion( 34, 20)), //Daris
    		new Zona(new Posicion(  0,  25), new Posicion( 34, -25), new Posicion( 26,   0), new Posicion(-34,-53), new Posicion( 34,  0)), //Chino
    		new Zona(new Posicion(-15,  52), new Posicion( 34,  20), new Posicion(  8,  32), new Posicion(-34,-53), new Posicion( 34, 20))  //yo
    };
    
    Zona zonaSaque[] = new Zona[]{
    		new Zona(new Posicion(-10, -42), new Posicion( 10,  -52)), //Lucho
    		new Zona(new Posicion(  0,   0), new Posicion(-10,   10)), //Gusta
    		new Zona(new Posicion(-34,   0), new Posicion( 10,-52.5)), //Tongha
    		new Zona(new Posicion(  0,   0), new Posicion( 34,-52.5)), //Dani
    		new Zona(new Posicion(  0,   0), new Posicion(-10,   10)), //Guille
    		new Zona(new Posicion(  0,   0), new Posicion(-10,   10)), //Dari
    		new Zona(new Posicion(-34,52.5), new Posicion( 10,    0)), //Juani
    		new Zona(new Posicion(  0,   0), new Posicion(-10,   10)), //Tano
    		new Zona(new Posicion(  0,   0), new Posicion(-10,   10)), //Daris
    		new Zona(new Posicion(  0,52.5), new Posicion( 34,    0)), //Chino
    		new Zona(new Posicion(  0,   0), new Posicion(-10,   10)), //yo
    };


}